package com.guojian.jdbc.mapper;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.springframework.dao.TypeMismatchDataAccessException;
import org.springframework.jdbc.core.SingleColumnRowMapper;
import org.springframework.util.ClassUtils;

/**
 * 
 * 
 * 
 * 移除了getColumnCount 必须=1的判断
 * 
 * 使用oracle分页时,使用ROWNUM会多出一列<br>
 * 
 * newSql = SELECT TOP 5 USER_ID FROM (SELECT ROW_NUMBER() OVER (ORDER BY ROW_ALIAS_1) PAGE_ROW_NUMBER, USER_ID FROM (SELECT USER_ID, user_id AS ROW_ALIAS_1 FROM SYS_USER) AS PAGE_TABLE_ALIAS) AS PAGE_TABLE_ALIAS WHERE PAGE_ROW_NUMBER > 1 ORDER BY PAGE_ROW_NUMBER
 * <br>
 * SELECT * FROM (  SELECT TMP_PAGE.*, ROWNUM ROW_NO FROM ( select USER_ID from SYS_USER  ORDER BY user_id ) TMP_PAGE WHERE ROWNUM <=  11 ) WHERE ROW_NO >  1
 * <br>
 * 
 * @author GuoJian
 *
 * @param <T>
 */
public class SingleColumnRowMapperOfPage<T> extends SingleColumnRowMapper<T> {

	private Class<?> requiredType;

	@SuppressWarnings("unchecked")
	@Override
	public T mapRow(ResultSet rs, int rowNum) throws SQLException {
		ResultSetMetaData rsmd = rs.getMetaData();

		//取第一列的数据,不判断数据有多少列,因为分页的时候在oracle下回产生ROWNUM,查询的列数,会多出一列,只需要把ROWNUM放在最后就可以
		//SELECT * FROM (  SELECT TMP_PAGE.*, ROWNUM ROW_NO FROM ( select USER_ID from SYS_USER  ORDER BY user_id ) TMP_PAGE WHERE ROWNUM <=  11 ) WHERE ROW_NO >  1

		Object result = getColumnValue(rs, 1, this.requiredType);
		if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
			try {
				return (T) convertValueToRequiredType(result, this.requiredType);
			} catch (IllegalArgumentException ex) {
				throw new TypeMismatchDataAccessException("Type mismatch affecting row number " + rowNum + " and column type '" + rsmd.getColumnTypeName(2) + "': " + ex.getMessage());
			}
		}
		return (T) result;
	}

	
	public SingleColumnRowMapperOfPage() {
	}
	
	public SingleColumnRowMapperOfPage(Class<T> requiredType) {
		this.requiredType = ClassUtils.resolvePrimitiveIfNecessary(requiredType);
	}

}
